package com.hangwei.aicabinet.manager;


import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.hangwei.aicabinet.net.API;
import com.hangwei.aicabinet.util.SPKey;
import com.hangwei.aicabinet.util.SPUtil;
import com.hangwei.aicabinet.util.Tools;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


/**
 * Author: zlc
 * Date: 2017/5/11.
 */

public class Retrofit2Manager {

    private static final String BASE_URL = API.BASE_URL_UNDER_LINE;
    private static final int Time_Out = 10;
    private static Retrofit2Manager retrofit2Manager;
    private static Retrofit retrofit;

    private Retrofit2Manager() {
    }

    public static Retrofit2Manager getInstance() {
        if (retrofit2Manager == null) {
            synchronized (Retrofit2Manager.class) {
                if (retrofit2Manager == null) {
                    retrofit2Manager = new Retrofit2Manager();
                }
            }
        }
        return retrofit2Manager;
    }

    public <T> T create(Class<T> clazz) {
        if (retrofit == null)
            retrofit = new Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .client(getOkhttpClient())
                    .baseUrl(BASE_URL)
                    .build();
        return retrofit.create(clazz);
    }


    private OkHttpClient getOkhttpClient() {
//        SSLSocketFactory sslSocketFactory = new SslContextFactory().getSslSocket().getSocketFactory();
//        OkHttpClient.Builder builder = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory);
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(Time_Out, TimeUnit.SECONDS);
        builder.readTimeout(Time_Out, TimeUnit.SECONDS);
        builder.writeTimeout(Time_Out, TimeUnit.SECONDS);

        builder.addInterceptor(new Interceptor() {
            @Override
            public okhttp3.Response intercept(@NonNull Chain chain) throws IOException {
                Request.Builder builder1 = chain.request()
                        .newBuilder()
                        .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
                        .addHeader("Connection", "keep-alive")
                        .addHeader("Accept", "*/*")
                        .addHeader("Access-Control-Allow-Origin", "*")
                        .addHeader("Access-Control-Allow-Headers", "X-Requested-With")
                        .addHeader("Vary", "Accept-Encoding");
                String appid = SPUtil.getString(SPKey.Account.APP_ID);
                String token = SPUtil.getString(SPKey.Account.TOKEN);
                if (!TextUtils.isEmpty(appid))
                    builder1.addHeader("appid", appid);
                if (!TextUtils.isEmpty(token))
                    builder1.addHeader("token", token);
                return chain.proceed(builder1.build());
            }
        });
        if (Tools.isDebug()) {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(Tools.isDebug() ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);
            builder.addInterceptor(interceptor);
        }
        return builder.build();
    }

    public void setCertificates(OkHttpClient.Builder okHttpClient, InputStream... certificates) {
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates) {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));

                try {
                    if (certificate != null)
                        certificate.close();
                } catch (IOException e) {
                }
            }

            SSLContext sslContext = SSLContext.getInstance("TLS");

            TrustManagerFactory trustManagerFactory =
                    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

            trustManagerFactory.init(keyStore);
            sslContext.init
                    (
                            null,
                            trustManagerFactory.getTrustManagers(),
                            new SecureRandom()
                    );
//            mOkHttpClient.setSslSocketFactory(sslContext.getSocketFactory());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
